#ifndef TINX_APIC_H
#define TINX_APIC_H

#include <tinx/types.h>

#define IA32_MSR_APIC_BASE 0x1B
#define IA32_APIC_ENABLE 0x800

#define LVT_DELIVERY_FIXED 0
#define LVT_DELIVERY_NMI (0x4 << 8)
#define LVT_TRIGGER_EDGE (0 << 15)
#define LVT_TRIGGER_LEVEL (1 << 15)
#define LVT_MASKED (1 << 16)
#define LVT_TIMER_ONESHOT (0 << 17)
#define LVT_TIMER_PERIODIC (1 << 17)

// Local APIC 寄存器枚举
enum APIC_REG_INDEX
{
    APIC_REG_ID = 0x020,
    APIC_REG_VERSION = 0x030,
    APIC_REG_TPR = 0x080,
    APIC_REG_EOI = 0x0B0,
    APIC_REG_LDR = 0x0D0,
    APIC_REG_DFR = 0x0E0,
    APIC_REG_SVR = 0x0F0,
    APIC_REG_ESR = 0x280,
    APIC_REG_ICR_LOW = 0x300,
    APIC_REG_ICR_HIGH = 0x310,
    APIC_REG_LVT_TIMER = 0x320,
    APIC_REG_LVT_PERF = 0x340,
    APIC_REG_LVT_LINT0 = 0x350,
    APIC_REG_LVT_LINT1 = 0x360,
    APIC_REG_LVT_ERROR = 0x370,
    APIC_REG_TIMER_INIT = 0x380,
    APIC_REG_TIMER_CURR = 0x390,
    APIC_REG_TIMER_DIV = 0x3E0
};

// 中断交付模式
enum APIC_DELIVERY_MODE
{
    ICR_FIXED = 0x000,
    ICR_LOWEST = 0x001,
    ICR_SMI = 0x002,
    ICR_NMI = 0x004,
    ICR_INIT = 0x005,
    ICR_STARTUP = 0x006
};

// 定时器模式
enum APIC_TIMER_MODE
{
    APIC_TIMER_ONESHOT = 0x00,
    APIC_TIMER_PERIODIC = 0x01,
    APIC_TIMER_TSC_DEADLINE = 0x02
};

// 分频器值
enum APIC_DIVIDE_VALUE
{
    APIC_DIVIDE_2 = 0x0,
    APIC_DIVIDE_4 = 0x1,
    APIC_DIVIDE_8 = 0x2,
    APIC_DIVIDE_16 = 0x3,
    APIC_DIVIDE_32 = 0x8,
    APIC_DIVIDE_64 = 0x9,
    APIC_DIVIDE_128 = 0xA,
    APIC_DIVIDE_1 = 0xB
};

#endif